import Vue from 'vue'
import axios from 'axios'
import router from '@/router'
import {
  Loading,
  Message,
  MessageBox,
  Notification
} from 'element-ui'
import store from '@/store'
const qs = require('qs')
let loadingInstance
let param
let body
axios.interceptors.request.use(config => {
  param = transferUrl(config.params)
  body = config.data
  if (process.env.NODE_ENV !== 'production') {
    console.debug('-> [' + config.method + ']' + config.url +
      (param == null ? '' : ('?' + param)) +
      (body == null ? '' : ('\n->' + JSON.stringify(config.data, null, ' '))))
  }
  if (config.loading) {
    loadingInstance = Loading.service({
      text: '请稍等',
      target: document.querySelector('.loadingtext')
    })
  }
  if (store.getters.token) {
    config.headers.common['x-access-token'] = btoa(store.getters.token)
  } else {
    config.headers.common['x-access-token'] = btoa(Vue.prototype.getLocalStorage('token'))
  }
  config.headers.common['user-id'] = Vue.prototype.getLocalStorage('operator')
  config.headers.common['client-type'] = 'WEB'
  return config
}, err => {
  if (loadingInstance) {
    loadingInstance.close()
  }
  Message.error({
    message: '请求超时!'
  })
  return Promise.resolve(err)
})
axios.interceptors.response.use(resp => {
  if (process.env.NODE_ENV !== 'production') {
    console.debug('<- [' + resp.config.method + ']' + resp.config.url + '->' + JSON.stringify(resp.data, null, ' '))
  }
  if (loadingInstance) {
    loadingInstance.close()
  }
  if (resp.data.message === 'SYS_SESSION_TIME_OUT') {
    window.localStorage.removeItem('token')
    window.localStorage.removeItem('operator')
    router.push({
      path: '/login'
    })
    return Promise.reject(resp)
  }
  return Promise.resolve(resp)
}, err => {
  if (process.env.NODE_ENV !== 'production') {
    console.debug('-_- [' + err.config.method + ']' + err.config.url + '->' + JSON.stringify(err.response.data, null, ' '))
  }
  if (loadingInstance) {
    loadingInstance.close()
  }
  if (err.response.data.message === 'SYS_SESSION_TIME_OUT') {
    window.localStorage.removeItem('token')
    window.localStorage.removeItem('operator')
    router.push({
      path: '/login'
    })
    return Promise.reject(err)
  }
  if (err.response.status === 504 || err.response.status === 404) {
    Message.error({
      message: '服务器被吃了⊙﹏⊙∥'
    })
  } else if (err.response.status === 403) {
    Message.error({
      message: '权限不足,请联系管理员!'
    })
  } else if (err.response.status === 500) {
    /** 提示根据errLevel等级提示 */
    switch (err.response.data.data.errLevel) {
      case '0':
        console.error('接口报错', err.response.data.data.errMsg)
        break
      case '2':
        Message.error({
          message: err.response.data.data.errMsg,
          duration: 4000,
          showClose: true
        })
        break
      case '5':
        MessageBox.confirm(err.response.data.data.errMsg, '严重错误', {
          confirmButtonText: '马上解决',
          type: 'error'
        })
        break

      default:
        Notification.error({
          message: err.response.data.data.errMsg
        })
        break
    }
  }
  return Promise.reject(err.response)
})

axios.defaults.baseURL = Vue.prototype.baseUrl

Vue.prototype.fetch = function fetch(apiType, params, body, cbFunc, errorFunc, showErr, loading) {
  axios({
    method: apiType.method,
    url: `${apiType.url}` + '?' + qs.stringify(params, {
      arrayFormat: 'repeat'
    }),
    data: body,
    params: null,
    headers: {
      'Content-Type': 'application/json',
      'api-version': apiType.apiVersion
    },
    loading: (loading == null || loading) && true
  }).then(resp => {
    if (resp.data.message && resp.data.message !== 'SUCCESS' && showErr !== false) {
      Message.error({
        message: resp.data.data
      })
      if (errorFunc) {
        errorFunc(resp.data)
      }
      return
    }
    if (cbFunc) {
      cbFunc(resp.data)
    }
  }, err => {
    if (errorFunc) {
      errorFunc(err.data)
    }
  })
}

Vue.prototype.request = function request(apiType, params, body, showErr) {
  return new Promise((resolve, reject) => {
    axios({
      method: apiType.method,
      url: `${apiType.url}` + '?' + qs.stringify(params, {
        arrayFormat: 'repeat'
      }),
      data: body,
      params: null,
      headers: {
        'Content-Type': 'application/json',
        'api-version': apiType.apiVersion
      }
    }).then(resp => {
      if (resp.data.message && resp.data.message !== 'Success' && showErr !== false) {
        Message.error({
          message: resp.data.data
        })
        reject(resp.data.data)
      }
      resolve(resp.data.data)
    }).catch(err => {
      reject(err.data.data)
    })
  })
}

Vue.prototype.download = function (apiType, fileName, params, body, cbfunc, errorfunc) {
  axios({
    method: apiType.method,
    url: `${apiType.url}`,
    data: body,
    params: params,
    // headers: {'Access-Control-Expose-Headers': 'Content-disposition'},
    responseType: 'blob'
  }).then(resp => {
    download(resp, fileName)
    if (cbfunc) {
      cbfunc(resp.data)
    }
  }, err => {
    if (errorfunc) {
      errorfunc(err.data)
    }
  })
}
Vue.prototype.upload = function (apiType, params, body, cbfunc, errorfunc) {
  axios({
    method: apiType.method,
    url: `${apiType.url}` + '?' + qs.stringify(params, {
      arrayFormat: 'repeat'
    }),
    data: body,
    params: null,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  }).then(resp => {
    if (cbfunc) {
      cbfunc(resp)
    }
  }, err => {
    if (errorfunc) {
      errorfunc(err)
    }
  })
}

function transferUrl(params) {
  if (!params) {
    return null
  }
  let param = Object.entries(params)
  let ret = ''
  for (let k in param) {
    ret += param[k][0] + '=' + encodeURIComponent(param[k][1]) + '&'
  }
  return ret.substring(0, ret.length - 1)
}

function download(res, fileName) {
  const content = res.data
  // 构造一个blob对象来处理数据
  const blob = new Blob([content])

  // 对于<a>标签，只有 Firefox 和 Chrome（内核） 支持 download 属性
  // IE10以上支持blob但是依然不支持download
  if ('download' in document.createElement('a')) { // 支持a标签download的浏览器
    const link = document.createElement('a') // 创建a标签
    link.download = fileName // a 标签添加属性
    link.style.display = 'none'
    link.href = URL.createObjectURL(blob)
    document.body.appendChild(link)
    link.click() // 执行下载
    URL.revokeObjectURL(link.href) // 释放url
    document.body.removeChild(link) // 释放标签
  } else { // 其他浏览器
    navigator.msSaveBlob(blob, fileName)
  }
}

export default fetch
